import * as types from './mutation-types'
import * as webchatTypes from './modules/webchat/mutation-types'
import * as emailTypes from './modules/email/mutation-types'
import * as orderTypes from './modules/order/mutation-types'
import * as socketTypes from './modules/socket-push/mutation-types'
import * as callTypes from './modules/call/mutation-types'
import * as monitorTypes from './modules/monitor/mutation-types'
import common from './api/common'
import * as m7Utils from '@/utils/m7Utils'
import loginApi from './api/login'
import user from './api/user'
import call from './api/call'
import webchat from './api/webchat'
import Vue from 'vue'
import { Message } from 'element-ui'
import { _initPrivateUploader } from '@/utils/qiniuUtils'
import m7dicMap from '@utils/m7dicMap'
import store from './'
import customer from './modules/customer/'
import callMolude from './modules/call/'
import webchatMolude from './modules/webchat/'
import email from './modules/email/'
import order from './modules/order/'
import monitor from './modules/monitor'
import cti from './modules/cti'
import workbench from './modules/workbench'
import business from './modules/business'
import km from './modules/km'
import sms from './modules/sms'
import questionnaire from './modules/questionnaire'
import qualityCheck from './modules/quality-check'
import intelligentQualityCheck from './modules/intelligentQualityCheck'
import report from './modules/report'
import socket from './modules/socket-push/'
import config from './modules/config'
import merchantConfig from './modules/merchantConfig'
import market from './modules/market'
import configApi from './api/config'
import webrtc from './modules/webrtc'
import xrobot from './modules/xrobot'
import md5 from 'md5'
import { queryMonitorQueueWarningCfg } from './modules/monitor/actions'
import { CDN_TYPE_QINIU } from '@/utils/constance'

function initVuexModules(store) {
  // console.log(intelligentQualityCheck)
  !store.state.customer && store.registerModule('customer', customer)
  !store.state.call && store.registerModule('call', callMolude)
  !store.state.webchat && store.registerModule('webchat', webchatMolude)
  !store.state.email && store.registerModule('email', email)
  !store.state.order && store.registerModule('order', order)
  !store.state.market && store.registerModule('market', market)
  !store.state.cti && store.registerModule('cti', cti)
  !store.state.webrct && store.registerModule('webrtc', webrtc)
  !store.state.xrobot && store.registerModule('xrobot', xrobot)
  !store.state.workbench && store.registerModule('workbench', workbench)
  !store.state.business && store.registerModule('business', business)
  !store.state.km && store.registerModule('km', km)
  !store.state.sms && store.registerModule('sms', sms)
  !store.state.questionnaire && store.registerModule('questionnaire', questionnaire)
  !store.state.qualityCheck && store.registerModule('qualityCheck', qualityCheck)
  !store.state.report && store.registerModule('report', report)
  !store.state.socket && store.registerModule('socket', socket)
  !store.state.monitor && store.registerModule('monitor', monitor)
  !store.state.config && store.registerModule('config', config)
  !store.state.intelligentQualityCheck && store.registerModule('intelligentQualityCheck', intelligentQualityCheck)
  !store.state.merchantConfig && store.registerModule('merchantConfig', merchantConfig)
}
export const initSystemConfig = ({ commit, state }, data) => {
  return common.initSystemConfig(data).then((response) => {
    let data = response
    // if (data.serverTime) {
    //   let beginTime = new Date('2018-05-15 00:00:00').getTime()
    //   let endTime = new Date('2018-05-17 18:00:00').getTime()
    //   if (data.serverTime >= beginTime && data.serverTime <= endTime) {
    //     data.isShowActivePage = true
    //   } else {
    //     data.isShowActivePage = false
    //   }
    // }
    let verify = data.is_open_slider || false
    // let verify = true
    commit(types.SET_VERIFY_SHOW, verify)
    commit(types.INIT_CONFIG, { data })
  })
}
export const getCaptchaAction = ({ commit, state }, data) => {
  return common.getCaptchaAction(data).then((response) => {
    return response
  })
}
export const checkAccountName = ({ commit, state }, data) => {
  return loginApi.checkAccountName(data).then((response) => {
    return response
  })
}

export const getRedirectRemind = ({ commit }) => {
  return webchat.getRedirectRemind({})
}
/**
 * 获取到座席的操作系统
 * */
export const collectAgentPCInfo = ({ commit, state }) => {
  let screenHeight = window.screen.height
  let screenWidth = window.screen.width
  let screenResolution = screenWidth + '*' + screenHeight
  let os = m7Utils.getOSInfo()
  let chromeVersion = ''
  if (navigator.userAgent.match(/chrome\/[\d.]+/gi)) {
    chromeVersion = navigator.userAgent.match(/chrome\/[\d.]+/gi)[0].replace(/[^0-9.]/gi, '') || '未知'
  } else {
    chromeVersion = '未知'
  }
  let data = {
    resolution: screenResolution,
    os: os,
    version: chromeVersion,
    userAgent: navigator.userAgent
  }
  loginApi.collectAgentPCInfo(data)
  return null
}
export const getIndustryDic = ({ commit, state }, data) => {
  return loginApi.getIndustryDic(data).then((response) => {
    return response
  })
}
export const updateAccountByHuaWei = ({ commit, state }, data) => {
  return loginApi.updateAccountByHuaWei(data).then((response) => {
    return response
  })
}
export const getCheckCode = ({ commit, state }, data) => {
  return loginApi.getCheckCode(data).then((response) => {
    return response
  })
}
export const checkAuthCode = ({ commit, state }, data) => {
  return loginApi.checkAuthCode(data).then((response) => {
    return response
  })
}
export const resetPassword = ({ commit, state }, data) => {
  return loginApi.resetPassword(data).then((response) => {
    return response
  })
}
export const getLoginSecretKey = ({ commit, state }, data) => {
  return loginApi.getLoginSecretKey(data).then((response) => {
    return response
  })
}
export const signIn = ({ commit, state, rootState, dispatch }, user) => {
  let _user = m7Utils.deepClone(user)
  if (_user.safeKey) {
    delete _user.password
  }
  if (user.safeKey) {
    delete user.safeKey
  }
  // _user.domain = window.location.hostname
  _user.domain = window.location.href.split('/')[2]
  return loginApi
    .loginToAuthCenter(_user)
    .then((response) => {
      let data = response
      let loginBody = document.getElementById('login-body')
      if (data.success) {
        if (data.account && data.account.account) {
          loginBody.setAttribute('account', data.account.account)
        }
        // if (data.data.mobileCheckToken) {
        //   commit(types.SET_QRCODE_TOKEN, { token: data.data.mobileCheckToken })
        //   let Auth = {
        //     loginName: user.loginName
        //   }
        //   loginApi.webLoginPollMobileAuth(Auth).then(response => {
        //   })
        //   return data
        // }
        // 动态初始化业务模
        initVuexModules(store)
        // 刷新，关闭网页提示
        window.onbeforeunload = function () {
          // 主动退出系统或者sessionId不存在直接退出
          if (state.exit || !window.sessionStorage.sessionId || !state.login) {
          } else {
            return m7Utils.m7Language('public.quitTips')
          }
        }
        window.onunload = function () {
          if (!rootState.kickOut) {
            dispatch('pushSocketLogout', { sessionId: data.sessionId })
          }
          // gio('clearUserId')
        }
        if (data.logType === 'bind' || data.lastCodeKey || user.logType === 'bind' || data.identifyCodeShow) {
          return data
        } else {
          commit(types.SIGNIN, { data })
          // commit(types.SET_CTI_UI_DESC)
          window.sessionStorage.setItem('sessionId', data.sessionId)
          let _str = data.sessionId + data.user.loginToken
          let loginToken = md5(m7Utils.Base64.encode(_str))
          window.sessionStorage.setItem('loginToken', loginToken)
          let form = JSON.parse(JSON.stringify(user))
          delete form.lastCodeKey
          delete form.authCode
          window.sessionStorage.setItem('loginData', JSON.stringify(form))
          // window.sessionStorage.setItem('notifySwitch', JSON.stringify({
          //   customerPlan: true
          // }))
          commit(webchatTypes.SET_WEBCHAT_AUTOCLAIM, { status: data.user.imClaimStatus || 'open' })
          //  邮件的状态用的是true和false
          var emailStatus = false
          if (data.user.emailClaimStatus === 'open') {
            emailStatus = true
          }
          if (data.user && data.user._id) {
            // gio('setUserId', data.user._id)
          }
          if (data.account && data.account.companyName) {
            console.log(data.account.companyName, '=======')
            // gio('people.set', 'companyName_ppl', data.account.companyName)
          }
          var autoOrderInitStatus = 'order'
          if (!data.user.autoOrderInitStatus || data.user.autoOrderInitStatus !== 'order') {
            autoOrderInitStatus = 'busy'
          }
          commit(orderTypes.SET_ORDER_RECEIVORDER, { autoOrderInitStatus: autoOrderInitStatus })
          commit(emailTypes.SET_EMAIL_AUTOCLAIM, { emailStatus: emailStatus })
          commit(socketTypes.UPDATE_SOCKET_PUSH_TOKEN, { token: data.token })
          return dispatch('getSocketVersion', { accountId: data.account && data.account.account })
            .then((versionData) => {
              return dispatch('initSocket', versionData)
                .then(() => {
                  commit(callTypes.SHOW_INTELLIGENT, data.account.intelliCallAssist)
                  dispatch('refreshWebchatMenuNum')
                  dispatch('refreshNoticeUndealNum')
                  dispatch('refreshEmailMenuNum')
                  dispatch('getFileDomin')
                  dispatch('getCurrentDicVersion')
                  dispatch('_checkUploadAddress')
                  return dispatch('initCache')
                })
                .then(() => {
                  // TODO 全局loadi
                  window.sessionStorage.setItem('ipCheck', state.session.account.ipCheck)
                  window.sessionStorage.setItem('emailCheck', state.session.account.emailCheck)
                  loginBody.className = ''
                  let msg = {
                    _id: data.user._id,
                    status: 'undeal'
                  }
                  dispatch('queryVideoInvite', msg)
                  return data
                })
            })
            .catch(() => {
              return dispatch('initSocket', {})
                .then(() => {
                  commit(callTypes.SHOW_INTELLIGENT, data.account.intelliCallAssist)
                  dispatch('refreshWebchatMenuNum')
                  dispatch('refreshNoticeUndealNum')
                  dispatch('refreshEmailMenuNum')
                  dispatch('getFileDomin')
                  dispatch('getCurrentDicVersion')
                  dispatch('_checkUploadAddress')
                  return dispatch('initCache')
                })
                .then(() => {
                  // TODO 全局loadi
                  window.sessionStorage.setItem('ipCheck', state.session.account.ipCheck)
                  window.sessionStorage.setItem('emailCheck', state.session.account.emailCheck)
                  loginBody.className = ''
                  let msg = {
                    _id: data.user._id,
                    status: 'undeal'
                  }
                  dispatch('queryVideoInvite', msg)
                  return data
                })
            })
        }
      } else {
        loginBody.className = ''
        if (response.message === 'unknow error!') {
          commit(types.SET_ERROR, 'message.loginfailed')
        }
        return data
      }
    })
    .catch((err) => {
      console.log(err)
      return { success: false }
    })
}
/**
 * 直接通过sessionId登录
 * @private
 */
export const signInBysessionId = ({ commit, state, rootState, dispatch }, user) => {
  return loginApi.signInBysessionId(user).then((response) => {
    let data = response
    let loginBody = document.getElementById('login-body')
    if (data.account && data.account.account) {
      document.getElementById('login-body').setAttribute('account', data.account.account)
    }
    // 动态初始化业务模
    initVuexModules(store)
    if (data.success) {
      // 刷新，关闭网页提示
      window.onbeforeunload = function () {
        // 主动退出系统或者sessionId不存在直接退出
        if (state.exit || !window.sessionStorage.sessionId || !state.login) {
        } else {
          return m7Utils.m7Language('public.quitTips')
        }
      }
      window.onunload = function () {
        if (!rootState.kickOut) {
          dispatch('pushSocketLogout', { sessionId: data.sessionId })
        }
      }
      commit(types.SIGNIN, { data })
      window.sessionStorage.setItem('sessionId', data.sessionId)
      // commit(webchatTypes.SET_WEBCHAT_AUTOCLAIM, {status: data.user.imClaimStatus})
      // commit(socketTypes.UPDATE_SOCKET_PUSH_TOKEN, {token: data.token})
      dispatch('getCurrentDicVersion')
      dispatch('_checkUploadAddress')
      dispatch('getFileDomin')
      return dispatch('initCache').then(() => {
        // TODO 全局loading
        loginBody.className = ''
        // commit(types.SET_CTI_UI_DESC)
        return data
      })
    } else {
      loginBody.className = ''
      commit(types.SET_ERROR, 'default_tips')
      return data
    }
  })
}
/**
 * 直接通过token登录
 * @private
 */
export const signInByToken = ({ commit, state, rootState, dispatch }, user) => {
  return loginApi.signInByToken(user).then((response) => {
    if (response.success) {
      let login = {
        loginName: response.loginName,
        password: response.password,
        extenType: response.extenType,
        login_busyType: true
      }
      window.sessionStorage.setItem('tokenLoginData', JSON.stringify(login))
      let token = response.token
      let phoneTokenInUse = token.phoneTokenInUse
      let extenType = token.extenType
      let module = token.module
      // 动态初始化业务模
      initVuexModules(store)
      login.domain = window.location.href.split('/')[2]
      return loginApi.loginToAuthCenter(login).then((response) => {
        let data = response
        data.phoneTokenInUse = phoneTokenInUse
        data.tokenModule = module
        data.extenType = extenType
        let loginBody = document.getElementById('login-body')
        if (data.account && data.account.account) {
          loginBody.setAttribute('account', data.account.account)
        }
        if (data.success) {
          // commit(types.SET_CTI_UI_DESC)
          // 刷新，关闭网页提示
          window.onbeforeunload = function () {
            // 主动退出系统或者sessionId不存在直接退出
            if (state.exit || !window.sessionStorage.sessionId || !state.login) {
            } else {
              return m7Utils.m7Language('public.quitTips')
            }
          }
          window.onunload = function () {
            if (!rootState.kickOut) {
              dispatch('pushSocketLogout')
            }
            // gio('clearUserId')
          }
          if (data.logType === 'bind' || data.lastCodeKey || data.identifyCodeShow) {
            return data
          } else {
            commit(types.SIGNINBYTOKEN, { data })
            window.sessionStorage.setItem('sessionId', data.sessionId)
            let _str = data.sessionId + data.user.loginToken
            let loginToken = md5(m7Utils.Base64.encode(_str))
            window.sessionStorage.setItem('loginToken', loginToken)
            let form = JSON.parse(JSON.stringify(user))
            delete form.lastCodeKey
            delete form.authCode
            window.sessionStorage.setItem('loginData', JSON.stringify(form))
            // window.sessionStorage.setItem('notifySwitch', JSON.stringify({
            //   customerPlan: true
            // }))
            commit(webchatTypes.SET_WEBCHAT_AUTOCLAIM, { status: data.user.imClaimStatus || 'open' })
            //  邮件的状态用的是true和false
            var emailStatus = false
            if (data.user.emailClaimStatus === 'open') {
              emailStatus = true
            }
            if (data.account && data.account.companyName) {
              // gio('people.set', 'companyName_ppl', data.account.companyName)
            }
            if (data.user && data.user._id) {
              // gio('setUserId', data.user._id)
            }
            console.log('ccc')
            commit(emailTypes.SET_EMAIL_AUTOCLAIM, { emailStatus: emailStatus })
            commit(socketTypes.UPDATE_SOCKET_PUSH_TOKEN, { token: data.token })
            return dispatch('getSocketVersion', { accountId: data.account && data.account.account })
              .then((versionData) => {
                return dispatch('initSocket', versionData)
                  .then(() => {
                    dispatch('refreshWebchatMenuNum')
                    dispatch('refreshNoticeUndealNum')
                    dispatch('refreshEmailMenuNum')
                    dispatch('getCurrentDicVersion')
                    dispatch('getFileDomin')
                    return dispatch('initCache')
                  })
                  .then(() => {
                    // TODO 全局loading
                    loginBody.className = ''
                    return data
                  })
              })
              .catch(() => {
                return dispatch('initSocket', {})
                  .then(() => {
                    dispatch('refreshWebchatMenuNum')
                    dispatch('refreshNoticeUndealNum')
                    dispatch('refreshEmailMenuNum')
                    dispatch('getCurrentDicVersion')
                    dispatch('getFileDomin')
                    return dispatch('initCache')
                  })
                  .then(() => {
                    // TODO 全局loading
                    loginBody.className = ''
                    return data
                  })
              })
          }
        } else {
          loginBody.className = ''
          commit(types.SET_ERROR, 'default_tips')
          return Promise.reject(response)
        }
      })
    } else {
      if (response.code && response.code === '405') {
        commit(types.SET_ERROR, 'loginTokenOccupy')
      } else {
        commit(types.SET_ERROR, response.message || 'default_tips')
      }
      return Promise.reject(response)
    }
  })
}
export const getCurrentDicVersion = ({ commit, state, dispatch }) => {
  return loginApi
    .getCurrentDicVersion()
    .then((response) => {
      if (response.success) {
        console.log(response.data)
        dispatch('_checkUploadAddress')
        commit(types.SET_DICVERSION, response.data)
      }
    })
    .catch((err) => {
      console.log(err)
    })
}
/**
 * 登录后查询上传服务器地址（公有云，私有云）
 * @private
 */
export const _checkUploadAddress = ({ commit, state, dispatch }) => {
  return loginApi
    .checkUploadAddress()
    .then((resp) => {
      if (resp.success) {
        _initPrivateUploader(resp)
      }
    })
    .catch((err) => {
      console.log(err)
    })
}
export const bindPhoneBeforeLogin = ({ commit, state, dispatch }, data) => {
  return loginApi
    .bindPhoneBeforeLogin(data)
    .then((response) => response)
    .catch((err) => {
      console.log(err)
    })
}

export const checkBeforeLogin = ({ commit, state, dispatch }, data) => {
  return loginApi
    .checkBeforeLogin(data)
    .then((response) => response)
    .catch((err) => {
      console.log(err)
    })
}

export const getLoginAuthCodeToken = ({ commit, state, dispatch }, data) => {
  return loginApi
    .getLoginAuthCodeToken(data)
    .then((response) => response)
    .catch((err) => {
      console.log(err)
    })
}
// export const webLoginPollMobileAuth = ({ commit, state, dispatch }, data) => {
//   return loginApi.webLoginPollMobileAuth(data)
//   .then(response => response)
//   .catch((err) => {
//     console.log(err)
//   })
// }

export const initPhone = ({ commit, state, dispatch }) => {
  let loginForm = window.sessionStorage.getItem('loginData')
  let rtcData = JSON.parse(loginForm)
  // 把之前的local的loginForm换成取session的loginData是为了解决有时候local取不到值报错导致电话条的请求不执行
  let account = state.session.account
  let loginName = state.session.user.loginName + '@' + account.name
  let password = state.session.user.password
  let extenType = 'gateway'
  let loginBusyType = window.sessionStorage.getItem('login_busy_type')
  if (rtcData && rtcData.extenType && rtcData.extenType === 'sip') {
    // dispatch('initWebRtc', {username: rtcData.loginName, pwd: rtcData.password})
  }
  // 获取状态
  let busyType = '1'
  if (loginForm && loginForm !== 'undefined') {
    // 防止parse报错
    loginForm = JSON.parse(loginForm)
    if (loginForm.login_busyType) {
      busyType = '0'
    }
    if (loginForm.extenType) {
      extenType = loginForm.extenType
    }
  }
  if (loginBusyType) {
    // token登录取不到繁忙状态
    if (loginBusyType === 'true') {
      busyType = '0'
    }
  }
  // token登陆budyType设置
  let loginTokenBusyType = window.sessionStorage.getItem('loginTokenBusyType')
  if (loginTokenBusyType) {
    if (loginTokenBusyType === '0') {
      busyType = '0'
    } else if (loginTokenBusyType === '1') {
      busyType = '1'
    }
    window.sessionStorage.removeItem('loginTokenBusyType')
  }
  if (state.session.extenType) {
    // token登录extenType的存储位置和正常登录的存储位置不同
    extenType = state.session.extenType
  }
  let pbxid = state.session.user.pbx
  let curpbx = ''
  // 获取pbx信息
  let pbxs = []
  getCache({ commit, state }, { type: 'accountPbx' }).then((res) => {
    pbxs = res
    for (let i = 0; i < pbxs.length; i++) {
      if (pbxs[i]._id === pbxid) {
        curpbx = pbxs[i]
        state.cti.globalLet.phone_pbxs[pbxs[i]._id] = pbxs[i]
        break
      }
    }
    let url = curpbx.assAddr
    // 更换录音访问地址头
    if (window.location.protocol === 'https:') {
      if (curpbx.assDomain) {
        // 对应计费pbx ass域名
        url = curpbx.assDomain
        if (url.substr(url.length - 1, url.length) === '/') {
          url = url.substr(0, url.length - 1)
        }
      }
    }
    let config = {
      monitor: true,
      proxy_url: url,
      extenType: extenType,
      password: password,
      user: loginName,
      busyType: busyType.toString(),
      pbxNick: curpbx.name,
      curPbx: curpbx._id,
      pbx_in_ip: curpbx._id,
      accountId: account.account,
      exten: state.session.user.exten
    }
    if (
      (state.session.user.idAmin && state.session.user.isAdmin === true) ||
      (state.session.user.type && state.session.user.type === 'manager')
    ) {
      config.monitor = true
    } else {
      config.monitor = false
    }
    queryMonitorQueueWarningCfg({}, { pbx: state.session.user.pbx })
      .then((resp) => {
        // 初始电话条之前，先请求监控的配置
        dispatch('getWSSupport', config)
        const data = resp.data || {}
        commit(monitorTypes.QUEUE_WARNING, { data })
      })
      .catch(() => {
        // 若监控配置的请求异常，不能影响电话条的初始化
        dispatch('getWSSupport', config)
      })
  })
}

export const initMenu = ({ commit, state }) => {
  let data = { idle: '' }
  return common
    .getUserInMenu(data)
    .then((response) => {
      let data = response
      let success = data.success
      if (success) {
        console.log('initMenu finish')
        commit(types.SET_MENU, data)
      } else {
        console.log('getMenuFail')
      }
    })
    .catch((error) => {
      Promise.reject('request_fail,' + error)
    })
}
export const getDicCache = ({ commit, state }, data) => {
  return common
    .getDicCache(data)
    .then((response) => {
      return response
    })
    .catch((error) => {
      Promise.reject('request_fail,' + error)
    })
}
export const initCache = ({ commit, state, dispatch }) => {
  let data = { idle: '' }
  return common
    .getDicCache(data)
    .then((response) => {
      let data = response
      commit(types.SET_DICMAP, { dicMap: data.dicMap })
      console.log(data.dicMap)
      getCache({ commit, state }, { type: 'tabUrlAddress' }) // 获取客户TAB页对接数据
      // getCache({ commit, state }, { type: 'qualityTasks' }) // 获取质检任务
      // getCache({ commit, state }, { type: 'qualityConditionTemplates' }) // 获取条件模板
      getCache({ commit, state }, { type: 'urls' }) // 获取首页对接
      getCache({ commit, state }, { type: 'custTmpls' }) // 客户模板
      getCache({ commit, state }, { type: 'custCategorys' }) // 技能组的获取
      getCache({ commit, state }, { type: 'exportTaskLimit' }) // // 初始化通话、客户、工单、聊天内容导出上限
      // getCache({ commit, state }, { type: 'callLabel' }) // 通话标签
      call.findOneAppDic({ name: '满意度调查选项' }).then((res) => {
        if (res.success && res.data && res.data.options && Array.isArray(res.data.options)) {
          let data = []
          let options = res.data.options
          for (let i = 0; i < options.length; i++) {
            let name = options[i].name
            let value = options[i].options[0].name
            // 二级满意度二级选项
            let children = []
            if (options[i].children && options[i].children.length > 0) {
              for (let k = 0; k < options[i].children.length; k++) {
                children.push({ name: options[i].children[k].displayName, value: options[i].children[k].name })
              }
            }
            data.push({ name, value, children })
          }
          // commit(types.SET_TYPE_DICDATA, {data: data, type: 'investigate'})
          console.log(data)
          console.log('investigateinvestigateinvestigateinvestigateinvestigate')
          m7dicMap.updateCache('investigate', data)
        }
      })
      call.queryCallLabelType().then((resp) => {
        if (resp.success && resp.data) {
          commit(callTypes.QUERY_CALL_LABEL_TYPE, resp.data) // 获取通话标签类型 eg: 单标签or多级标签
        } else if (!resp.success) {
          commit(types.SET_ERROR, 'message.getLabelTypeFail')
        }
      })
      dispatch('getExtenAssignRecord', { account: store.state.session.account.account }).then((res) => {
        commit(types.SET_REMOTE_AGENTS, res.extenAssign || [])
      })
      // 这里面放的是必须登录后就同步加载完毕的数据,如果不是,就放到上面,异步去加载就行
      return Promise.all([
        getCache({ commit, state }, { type: 'guidance', loadFromServer: true }), // 新手引导
        getCache({ commit, state }, { type: 'options' }), // 字典
        getCache({ commit, state }, { type: 'queues' }), // 通话 技能组
        getCache({ commit, state }, { type: 'agents' }) // 坐席
      ])
    })
    .catch((error) => {
      Promise.reject('request_fail,' + error)
    })
}
/*
 * 以下为dic本地数据缓存入localStorage操作。
 * 1.调用getCache时，先判断vuex有无数据，如果没有，再判断localStorage内是否有本地版本，
 * 如果有，取出本地版本号与服务器版本号做对比，如果大于等于，使用并存入vuex，如果低于服务器版本，调用接口去服务器取出数据，更新本地缓存并存入vuex。
 * 2.数据量大小说明， chrome localStorage大小限制为500万字节。
 * 数据溢出处理方式：
 * 1.localStorage存入数据格式为 ： @Object 账号id:{[type]:data}
 * 同时使用数组localCacheArray 记录存入的账号数 [id1, id2, id3]，写入数据同时将账号push进数组。
 * 2.写入数据时如果出错判断数据溢出，取出数组中最早的账号，移除对应缓存，然后再次尝试写入。
 * */
let localRead = (key) => {
  return window.localStorage.getItem(key)
}
let ReadCurrentlocal = (sid, type) => {
  if (localRead(sid) !== null) {
    let localcache = JSON.parse(localRead(sid))
    if (localcache && localcache[type]) {
      return localcache[type]
    } else {
      return false
    }
  } else {
    return false
  }
}
let setCurrentlocal = (sid, type, data) => {
  let localcache = {}
  let localCacheArray = []
  if (localRead(sid) !== null) {
    localcache = m7Utils.deepClone(JSON.parse(localRead(sid)))
  }
  if (localRead('localCacheArray') !== null) {
    localCacheArray = JSON.parse(localRead('localCacheArray'))
  }
  localcache[type] = m7Utils.deepClone(data)
  console.log('写入localStorage,type=' + type, data)
  console.log('当前缓存字段共' + Object.keys(localcache).length + ', 字节数总计为' + JSON.stringify(localcache).length)
  if (localCacheArray.indexOf(sid) === -1) {
    localCacheArray.push(sid)
  }
  try {
    localWrite('localCacheArray', JSON.stringify(localCacheArray))
    localWrite(sid, JSON.stringify(localcache))
  } catch (err) {
    if (err.name === 'QuotaExceededError') {
      console.log('已超出本地存储大小上限')
      // let deletelocalArray = JSON.parse(localRead('localCacheArray'))
      // localRemove(deletelocalArray[0])
      // deletelocalArray.splice(0, 1)
      // localWrite('localCacheArray', JSON.stringify(deletelocalArray))
      // setCurrentlocal(sid, type, data)
    }
  }
}
let localWrite = (key, value) => {
  return window.localStorage.setItem(key, value)
}
// let localRemove = (key) => {
//   return window.localStorage.removeItem(key)
// }
// let localClearAll = () => {
//   return window.localStorage.clear()
// }
export const getCache = ({ commit, state }, req, retryTimes = 1) => {
  console.log(req)
  if (retryTimes > 3) {
    return
  }
  // 之前是通过座席id获取，现在通过账号获取
  let sid = state.session.user && state.session.user.account ? state.session.user.account : ''
  let type = req.type // type是调用方法等的类型
  let loadFromServer = req.loadFromServer // 是否从服务端获取数据
  let id = req.id
  let currentVersion = 0
  let localCache
  // 如果没有传入type字段直接返回空数组
  if (!type) {
    return []
  }
  // 通过type从vuex中读取最新的版本号，找到直接break,不用继续执行
  if (state && state.dicVersion && state.dicVersion instanceof Array && state.dicVersion.length > 0) {
    state.dicVersion.forEach((item) => {
      if (item.type === type) {
        currentVersion = item.version
      }
    })
  }
  function getFetchData() {
    return new Promise((resolve, reject) => {
      let data = { type: type }
      common
        .getDicCache(data)
        .then((response) => {
          if (type === 'agents' || type === 'custCategorys') {
            commit(types.updatedicMapGetterVersion)
          }
          if (response.success) {
            m7dicMap.updateCache(type, response.data)
            let options = m7dicMap.getCache('options')
            if (options) {
              cleanMarkDic({ commit, state }, options)
            }
            // 如果response.version没有值本地不做缓存
            if (response.version !== undefined) {
              // '读取 from Server,type = ' + type + '对比版本号' + currentVersion + '最新版本号' + response.version
              setCurrentlocal(sid, type, response)
            }
          } else {
            m7dicMap.updateCache(type, [])
          }
          // resolve(getCache({commit, state}, {type: type, id: id}, ++retryTimes))
          resolve(m7dicMap.getCache(type, id))
        })
        .catch(() => {
          if (retryTimes === 3) {
            commit(types.SET_ERROR, 'getCacheError')
          }
          // commit(types.SET_TYPE_DICDATA, {data: null, type: type})
          // resolve(getCache({commit, state}, {type: type, id: id}, ++retryTimes))
          m7dicMap.updateCache(type, null)
          resolve(getCache({ commit, state }, { type: type, id: id }, ++retryTimes))
        })
    })
  }
  // console.log('测试：' + type + '本地版本' + (localCache && localCache.version) + ',对比版本' + currentVersion)
  // 第一步 loadFromServer 为true 说明要从服务端获取
  // 第二步 否则的话先判定全局的data是否有值，如果有从全局取，否则的话从local取
  // 第二步都步符合从服务端取
  if (loadFromServer) {
    return getFetchData()
  } else {
    let typeData = m7dicMap.getCache(type) // 读取缓存的字段，如果存在返回数据，不存在返回false
    if (typeData) {
      if (id) {
        for (let i = 0; i < typeData.length; i++) {
          if (typeData[i]._id === id) {
            return Promise.resolve(m7Utils.copy(typeData[i]))
          }
        }
        return Promise.resolve(null)
      }
      return Promise.resolve(typeData)
    } else {
      localCache = ReadCurrentlocal(sid, type)
      if (
        localCache &&
        localCache.version &&
        (localCache.version > currentVersion || localCache.version === currentVersion) &&
        currentVersion !== 0
      ) {
        // console.log('读取 from localStorage, type =' + type + '本地版本' + localCache.version + ',对比版本' + currentVersion)
        m7dicMap.updateCache(type, localCache.data)
        if (type === 'agents' || type === 'custCategorys') {
          commit(types.updatedicMapGetterVersion)
        }
        if (id) {
          for (let i = 0; i < localCache.data.length; i++) {
            if (localCache.data[i]._id === id) {
              return Promise.resolve(m7Utils.copy(localCache.data[i]))
            }
          }
          return Promise.resolve(null)
        }
        return Promise.resolve(localCache.data)
      } else {
        return getFetchData()
      }
    }
  }
}
export const getDicCacheByValue = ({ state }, req) => {
  let type = req.type || ''
  let value = req.value
  // let cache = state.session.dicMap[type] || []
  let cache = m7dicMap.getCache(type) || []
  if (value) {
    for (let i = 0; i < cache.length; i++) {
      if (cache[i].code_value === value) {
        return m7Utils.copy(cache[i])
      }
    }
    return null
  }
  return cache
}

export const getCacheByKey = ({ commit, state }, req) => {
  return new Promise((resolve, reject) => {
    let type = req.type
    let key = req.key
    let value = req.value
    type = type || ''
    getCache({ commit, state }, { type: type }).then((cache) => {
      for (let i = 0; i < cache.length; i++) {
        let cacheItem = cache[i]
        if (cacheItem[key] === value) {
          resolve(cacheItem)
          break
        }
      }
      resolve(null)
    })
  })
}

export const getDicCacheName = ({ commit, state }, req) => {
  let type = req.type
  let value = req.value
  type = type || ''
  value = value || ''
  return getCache({ commit, state }, { type: type }).then((dic) => {
    for (let i = 0; i < dic.length; i++) {
      if (dic[i].code_value === value) {
        return dic[i].code_name
      }
    }
    return value
  })
}

export const addCache = ({ commit, state }, req) => {
  let type = req.type
  let data = req.data
  if (data) {
    getCache({ commit, state }, { type: type, id: data._id }).then((addData) => {
      if (!addData) {
        commit(types.PUSH_TYPE_DICDATA, { data: data, type: type })
      }
    })
  }
}

export const removeCache = ({ commit, state }, req) => {
  let type = req.type
  let id = req.id
  getCache({ commit, state }, { type: type }).then((cache) => {
    if (cache) {
      for (var i = 0; i < cache.length; i++) {
        if (cache[i]._id === id) {
          cache.splice(i, 1)
          break
        }
      }
    }
  })
}

export const updateCache = ({ commit, state }, req) => {
  let type = req.type
  let id = req.id
  let data = req.data
  getCache({ commit, state }, { type: type }).then((cache) => {
    if (cache) {
      for (var i = 0; i < cache.length; i++) {
        if (cache[i]._id === id) {
          cache[i] = data
          break
        }
      }
    }
  })
}

export const refreshCache = ({ commit, state }, req) => {
  let type = req.type
  let data = req.data
  if (!type) {
    return
  }
  data = data || []
  commit(types.SET_TYPE_DICDATA, { data })
}

/**
 * 从数据库获取数据更新缓存
 * @param type
 * @returns {Array}
 */
export const refreshCacheFromDb = ({ commit, state }, req) => {
  let type = req.type
  if (!type) {
    return []
  }
  let data = { type: type }
  return common
    .getDicCache(data)
    .then((response) => {
      let resData = response
      if (resData.success) {
        // commit(types.SET_TYPE_DICDATA, {data: resData.data, type: type})
        m7dicMap.updateCache(type, resData.data)
        let options = m7dicMap.getCache('options')
        if (options) {
          cleanMarkDic({ commit, state }, options)
        }
      } else {
        // commit(types.SET_TYPE_DICDATA, {data: [], type: type})
        m7dicMap.updateCache(type, [])
      }
      getCache({ commit, state }, { type: type })
    })
    .catch((error) => {
      console.log(error)
      // state.session.dicMap[type] = []
      m7dicMap.updateCache(type, [])
      getCache({ commit, state }, { type: type })
    })
}

export const cleanMarkDic = ({ commit, state }, diccm) => {
  // let oneFlag = []
  // let twoFlag = []
  // let threeFlag = []
  // for (let i = 0; i < diccm.length; i++) {
  //   let options = diccm[i].options || []
  //   for (let m = 0; m < options.length; m++) {
  //     if (options[m] !== '' && (options[m].state)) {
  //       if (options[m].state === '1') {
  //         oneFlag.push(options[m].key)
  //         continue
  //       }
  //       options[m].options = options[m].options || []
  //       for (let j = 0; j < options[m].options.length; j++) {
  //         let options1 = options[m].options
  //         if (options1[j] !== '') {
  //           if (options1[j].state === '1') {
  //             twoFlag.push(options1[j].key)
  //             continue
  //           }
  //           options1[j].options = options1[j].options || []
  //           for (let k = 0; k < options1[j].options.length; k++) {
  //             let options2 = options1[j].options
  //             if (options2[k] && (options2[k].state === '1')) {
  //               threeFlag.push(options2[k].key)
  //             }
  //           }
  //         }
  //       }
  //     }
  //   }
  // }
  // for (let i = 0; i < diccm.length; i++) {
  //   let options = diccm[i].options || []
  //   for (let m = 0; m < options.length; m++) {
  //     if (options[m] !== '') {
  //       if (oneFlag.length > 0) {
  //         if (oneFlag.indexOf(options[m].key) !== -1) {
  //           options.splice(m, 1)
  //           m = m - 1
  //           continue
  //         }
  //       }
  //       options[m].options = options[m].options || []
  //       for (let j = 0; j < options[m].options.length; j++) {
  //         let options1 = options[m].options
  //         if (options1[j] !== '') {
  //           if (twoFlag.length > 0) {
  //             if (twoFlag.indexOf(options1[j].key) !== -1) {
  //               options1.splice(j, 1)
  //               continue
  //             }
  //           }
  //           options1[j].options = options1[j].options || []
  //           for (let k = 0; k < options1[j].options.length; k++) {
  //             let options2 = options1[j].options
  //             if (options2[k] !== '') {
  //               if (threeFlag.length > 0) {
  //                 if (threeFlag.indexOf(options2[k].key) !== -1) {
  //                   options2.splice(k, 1)
  //                   continue
  //                 }
  //               }
  //             }
  //           }
  //         }
  //       }
  //     }
  //   }
  // }
  // commit(types.SET_OPTIONS_DICMAP, diccm)
  diccm.forEach((item) => {
    m7Utils.deleteDisabledOption(item)
  })
  m7dicMap.updateCache('options', diccm)
}

export const getToken = ({ commit, state, dispatch }) => {
  let eventLogData = {
    timeStart: new Date().getTime(),
    apiType: 'getToken',
    type: 'requestTimeout',
    sessionId: state.session.sessionId
  }
  return user.getTokenId().then((response) => {
    if (response && response.success) {
      eventLogData.endTime = new Date().getTime()
      eventLogData.time = eventLogData.endTime - eventLogData.timeStart
      let account = state.session.account.account
      if (eventLogData.endTime - eventLogData.timeStart > 2000 && account === 'N00000000011') {
        dispatch('collectEventLog', eventLogData)
      }
    }
    let data = response
    commit(types.USER_TOKEN, { data })
    return response
  })
}
export const getTokenById = ({ commit, state }, data) => {
  return user.getTokenById(data).then((response) => {
    return response
  })
}
export const userEdit = ({ commit }, data) => {
  return user.editUser(data).then((response) => {
    if (response.success) {
      if (data.password) {
        data.password = data.password
      }
      commit(types.USER_EDIT, data)
    } else {
      let repeatList = response.repeatList // 修改座席资料时重复提示
      if (repeatList && repeatList.length) {
        let temp = m7Utils.m7Language('operationFail1')
        let tempFlag = false
        for (var i = 0; i < response.repeatList.length; i++) {
          if (response.repeatList[i] === 'name') {
            temp += '[' + m7Utils.m7Language('public.name') + ']'
            tempFlag = true
          }
          if (response.repeatList[i] === 'exten') {
            temp += '[' + m7Utils.m7Language('public.jobNumber') + ']'
            tempFlag = true
          }
          if (response.repeatList[i] === 'loginName') {
            temp += '[' + m7Utils.m7Language('agent.agentName') + ']'
            tempFlag = true
          }
        }
        if (tempFlag) {
          Message({ message: temp, type: 'error', duration: 3000 })
        } else {
          if (response.repeatList.indexOf('mobile') > -1) {
            Message({ message: `该号码已被${response.agentInfo}绑定，请检查您的号码`, type: 'error', duration: 3000 })
          } else if (response.repeatList.indexOf('email') > -1) {
            Message({ message: `该邮箱已被${response.agentInfo}绑定，请检查您的邮箱`, type: 'error', duration: 3000 })
          } else if (response.repeatList.indexOf('callerIDNum') > -1) {
            Message({ message: `该外显号已被${response.agentInfo}绑定，请检查`, type: 'error', duration: 3000 })
          }
        }
      }
    }
    return response.success
  })
}

export const getImTestQiniuToken = ({ commit }, data) => {
  return common.getWeinxinQiniuUptoken(data)
}

/**
 * 更改邀请多方会话的窗口的展示情况
 * */
export const changeInvite = ({ commit }, data) => {
  commit(types.CHANGE_STATE_INVITECON, data)
}

/**
 * 重新发送邮箱验证码
 * @param {Object} data
 * @param {String} data.lastCodeKey
 */
export const retryMail2Authcode = ({ commit }, data) => {
  return loginApi.retryMail2Authcode(data).catch((err) => {
    console.error(err)
    // 'message.default_tips'
  })
}

/**
 * /
 * @param  {[type]} options.commit [存储根据业务异步动态生成组件]
 * @param  {[type]} data           [组件名， 组件实例]
 * @return {[type]}                [description]
 */
export const registerRouter = ({ commit }, data) => {
  Vue.component(data.name, data.component)
  commit('ADD_ROUTES', data)
}

export const pushSocketLogout = ({ state, commit }) => {
  let data = { sessionId: state.session.user._id }
  common.pushSocketLogout(data)
  common.clearSession(data)
}
/**
 * 登陆刷新时查询未处理的视频请求
 * @param data
 * */
export const queryVideoInvite = ({ commit }, data) => {
  return webchat.queryVideoInvite(data).then((response) => {
    if (response.success && response.data) {
      let inviteMsg = {
        videoInviteSessionid: response.data.sessionId,
        // videoInviteToken: response.data.token,
        platform: response.data.platform || '',
        roomId: response.data.roomId || '',
        videoType: response.data.videoType || '',
        password: response.data.password || ''
      }
      commit(webchatTypes.UPDATE_VIDEO_INVITE_STATUS, true)
      commit(webchatTypes.UPDATE_VIDEO_INVITE_DATA, inviteMsg)
      if (response.data.videoType && response.data.videoType === 'voice') {
        commit(webchatTypes.UPDATE_HIDE_VIDEO_CAMERA_STATU, true)
      }
    }
  })
}
/**
 * 判断混合云还是公有云
 */
export const checkAccountHttps = ({ commit }, data) => {
  return loginApi
    .checkAccountHttps(data)
    .then((rep) => {
      if (rep.success) {
        return rep
      }
    })
    .catch(() => {
      // 'message.default_tips'
    })
}
// 更新新手指导状态
export const updateGuidance = ({ commit }, data) => {
  let actionData = {}
  actionData[data.key] = data.status
  return loginApi
    .updateGuidance(actionData)
    .then((rep) => {
      if (rep.success) {
        return rep
      }
    })
    .catch((error) => {
      console.log(error)
      // 'message.default_tips'
    })
}
// 更新视图状态
export const updateViewSwitch = ({ commit }, data) => {
  // module	string 所属模块  status string 旧版 old / 新版 new
  return loginApi
    .updateViewSwitch(data)
    .then((rep) => {
      if (rep.success) {
        return rep
      }
    })
    .catch((error) => {
      console.log(error)
      // 'message.default_tips'
    })
}
// 修改远程控制信息
export const updateRemoteControlInfo = ({ commit }, data) => {
  commit(types.updateRemoteControlInfo, data)
}
// 根据远程码获取远程地址信息
export const queryRemoteControlAdd = ({ commit }, data) => {
  return loginApi
    .queryRemoteControlAdd(data)
    .then((req) => {
      return req
    })
    .catch((error) => {
      console.log(error)
      // 'message.default_tips'
    })
}

// 获取 cc 地址  cc通话设置 嵌入kf 用
export const getCCConfigUrl = ({ commit }, data) => {
  return common
    .getCCConfigUrl(data)
    .then((req) => {
      return req
    })
    .catch((error) => {
      console.log(error)
      // 'message.default_tips'
    })
}
// 记录信息的接口，可公用，目前用来记录在线咨询新会话接入后的是否弹出提醒，传不同参数就能在日志系统中查询
export const collectEventLog = ({ commit }, data) => {
  return common
    .collectLog(data)
    .then((req) => {
      return req
    })
    .catch((error) => {
      console.log(error)
      // 'message.default_tips'
    })
}

// 获取高级搜索自定义配置
export const getAdvSearchConfig = ({ commit }, { searchType }) => {
  // return new Promise(function (resolve) {
  //   var jsonString = window.localStorage['AdvSearchConfig_' + searchType]
  //   var config = null
  //   try {
  //     config = JSON.parse(jsonString)
  //   } catch (error) {

  //   }

  //   resolve({
  //     searchType,
  //     config
  //   })
  // })
  return configApi
    .getAdvSearchConfig({
      type: searchType
    })
    .then((req) => {
      var configs = req && req.data && req.data.configs
      if (!configs || configs.length === 0) {
        configs = {}
      }

      return configs
    })
    .catch((error) => {
      console.log(error)
    })
}

// 保存高级搜索自定义配置
export const saveAdvSearchConfig = ({ commit }, { searchType, config }) => {
  return configApi
    .saveAdvSearchConfig({
      type: searchType,
      configs: config
    })
    .then(() => {
      return {
        success: true
      }
    })
    .catch(() => {
      return {
        success: false
      }
    })
  // return new Promise(function (resolve) {
  //   window.localStorage['AdvSearchConfig_' + searchType] = JSON.stringify(config)
  //   resolve({
  //     success: true
  //   })
  // })
}

/**
 * 导出excel
 * @param {Object} data.Query 导出条件
 * @param {String} data.Method 导出方法
 */
export const exportXls = ({ commit }, data) => {
  return common
    .exportXls(data)
    .then((response) => {
      if (response.success) {
        commit(types.SET_FILEDOWNLOAD, { path: response.path, isSession: true })
      }
      return response
    })
    .catch((error) => {
      console.log(error)
      // 'message.default_tips'
    })
}
/**
 * 保存标签页顺序
 */
export const saveToolbarTabPosition = ({ commit }, data) => {
  return configApi
    .saveToolbarTabPosition(data)
    .then((response) => {
      if (response.success) {
        return response
      }
    })
    .catch((error) => {
      console.log(error)
      // 'message.default_tips'
    })
}
export const updateDynamicTemplate = ({ commit }, data) => {
  return configApi
    .updateDynamicTemplate(data)
    .then((response) => {
      if (response.success) {
        return response
      }
    })
    .catch((error) => {
      console.log(error)
      // 'message.default_tips'
    })
}
/**
 * 查询标签页顺序
 */
export const queryToolbarTabPosition = ({ commit }, data) => {
  return configApi
    .queryToolbarTabPosition(data)
    .then((response) => {
      if (response.success) {
        return response
      }
    })
    .catch((error) => {
      console.log(error)
      // 'message.default_tips'
    })
}

export const getFileDomin = ({ commit }, data) => {
  return common.getFileDomin({}).then((res) => {
    commit(types.IS_USE_QINIU, res.cdnConfType === CDN_TYPE_QINIU)
    if (res.success && res.fileDomain) {
      commit(types.FileDOMAIN, res.fileDomain)
    }
  })
}
